import Form, {
  type FormInstance,
  type FormProps,
} from "ant-design-vue/es/form";
import {
  computed,
  defineComponent,
  reactive,
  ref,
  watch,
  type PropType,
} from "vue";
import type { ProFormColType } from "../interface";
import Row from "ant-design-vue/es/grid/Row";
import Col, { type ColProps } from "ant-design-vue/es/grid/Col";
import { renderDescItem } from "../utils/renderDesc";
import { renderFormItem } from "../utils/renderField";
import { modalVal } from "../utils";

export type ProFormExpose = FormInstance;

export default defineComponent({
  name: "ProForm",
  props: {
    /**表单/详情初始值 */
    initialValues: {
      type: Object as PropType<Record<string, any>>,
    },
    /**表单/详情列配置 */
    columns: {
      required: true,
      type: Array as PropType<ProFormColType<any>[]>,
      default: () => [],
    },
    /**Form组件的props参数 */
    formProps: {
      type: Object as PropType<FormProps>,
    },
    /** Col的属性，用于控制默认布局 */
    colProps: {
      type: Object as PropType<ColProps>,
      default: () => ({
        span: 12,
        xs: 24,
        sm: 24,
        md: 12,
        lg: 12,
        xl: 12,
        xxl: 12,
      }),
    },
    /** 表单/详情的模式，read为详情模式，write为表单模式 */
    mode: {
      type: String as PropType<"read" | "write">,
      default: "write",
    },
  },
  setup(props, ctx) {
    const formRef = ref<FormInstance>();
    const modal = reactive({});

    ctx.expose({
      /** 清除校验结果 */
      clearValidate: (name?: string) => {
        formRef.value?.clearValidate(name);
      },
      /** 获取表单所有字段的值 */
      getFieldsValue: () => {
        return formRef.value?.getFieldsValue();
      },
      /** 重置表单所有字段的值 */
      resetFields: (name?: string) => {
        formRef.value?.resetFields(name);
      },
      /** 滚动到指定字段的位置 */
      scrollToField: (name: string) => {
        formRef.value?.scrollToField(name);
      },
      /** 校验表单所有字段 */
      validate: () => {
        return formRef.value?.validate();
      },
      /** 校验指定字段 */
      validateFields: (nameList: string[], options: any) => {
        return formRef.value?.validateFields(nameList, options);
      },
    });

    /**递归props.columns 过滤出hideInForm为false的 */
    const columns = computed(() => {
      // 递归过滤函数，用于处理多级嵌套的 columns
      const filterColumns = (items: ProFormColType<any>[]) => {
        const result: ProFormColType<any>[] = [];
        for (const item of items) {
          if (item.hideInForm !== true) {
            const newItem = { ...item };
            if (newItem.children && newItem.children.length > 0) {
              newItem.children = filterColumns(newItem.children);
            }
            result.push(newItem);
          }
        }
        return result;
      };

      return filterColumns(props.columns);
    });

    /**
     * 递归渲染表单或描述项的函数
     * @param items 待渲染的列配置项数组
     * @returns 渲染后的 VNode 数组
     */
    const renderItems = (items: ProFormColType<any>[]) => {
      return items.map((item) => {
        // 如果是列分组，递归渲染子项
        if ("children" in item) {
          return (
            <Col span={24}>
              <header class="mt-[20px] mb-[15px] text-[20px] font-bold">
                {item.title}
              </header>
              <Row gutter={[25, 0]}>{renderItems(item.children || [])}</Row>
            </Col>
          );
        } else {
          // 如果是普通列，渲染表单字段
          const colProps = { ...props.colProps, ...(item.colProps || {}) };
          if (["table", "image", "file"].includes(item.type || "")) {
            colProps.span = 24;
            colProps.xs = 24;
            colProps.sm = 24;
            colProps.md = 24;
            colProps.lg = 24;
            colProps.xl = 24;
            colProps.xxl = 24;
          }
          return (
            <Col {...colProps}>
              {props.mode === "write"
                ? renderFormItem(item, modal)
                : renderDescItem(item, modal)}
            </Col>
          );
        }
      });
    };

    watch(
      () =>
        [props.initialValues, formRef.value] as [
          Record<string, any> | undefined,
          FormInstance | undefined
        ],
      ([val, form]) => {
        if (!form) return;
        for (const key in val) {
          modalVal(modal, key).set(val[key]);
        }
      },
      { immediate: true, deep: true }
    );

    return () => (
      <div class="pro-form">
        {/* <pre>columns： {JSON.stringify(columns.value, null, 2)}</pre>
        <br />
        <br />
        modal： {JSON.stringify(modal)}
        <br />
        =============================================
        <br /> */}
        <Form ref={formRef} model={modal} {...(props.formProps || {})}>
          <Row gutter={[25, 0]}>{renderItems(columns.value)}</Row>
          <div class="flex justify-end">{ctx.slots.after?.()}</div>
        </Form>
      </div>
    );
  },
});
